package cn.harperDog.reflect;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * @author hua
 * @description
 * @date 2022/3/3
 * <p>
 * 给一个类名，根据该类名加载类
 */
public class LoadClass {
    public static void main(String[] args) throws ClassNotFoundException {
        loadClass1();
    }

    public static void loadClass1() {
        ClassLoader myLoader = new ClassLoader() {
            @Override
            public Class<?> loadClass(String name) throws ClassNotFoundException {
                try {
                    String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class";
                    InputStream is = getClass().getResourceAsStream(fileName);

                    //这个if判断必须有
                    if (is == null) {
                        return super.loadClass(name);
                    }

                    byte[] b = new byte[is.available()];
                    is.read(b);

                    return defineClass(name, b, 0, b.length);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return super.loadClass(name);
            }
        };

        try {
            //这里必须包含包名
            Class<?> aClass = myLoader.loadClass("cn.harperDog.reflect.LoadClass");
            Object obj = aClass.newInstance();

            System.out.println("同一个类型？" + aClass.isAssignableFrom(LoadClass.class));
            System.out.println(obj instanceof LoadClass);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void loadClass2() throws ClassNotFoundException {
        ClassLoader m = new MyClassLoader();
        Class clazz = m.loadClass("cn.harperDog.reflect.A");

        m = new MyClassLoader();
        Class clazzNew = m.loadClass("cn.harperDog.reflect.A");

        System.out.println(clazz == clazzNew);
    }
}

class MyClassLoader extends ClassLoader {
    @Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        File f = new File("C:/D/workspace/examination/target/classes/" + name.replace(".", "/").concat(".class"));

        if (!f.exists()) return super.loadClass(name);

        try {

            InputStream is = new FileInputStream(f);

            byte[] b = new byte[is.available()];
            is.read(b);
            return defineClass(name, b, 0, b.length);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return super.loadClass(name);
    }
}